package dao.models;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Session {
    private List<Question> questions = new ArrayList<Question>();
    private Map<Question, Boolean> answerMap = new HashMap<Question, Boolean>();
    private int current = 0;
    private final List<Chapter> chapters;

    public Session(List<Chapter> chapters) {
	this.chapters = chapters;
	for (Chapter chapter : chapters) {
	    questions.addAll(chapter.getQuestions());
	}
    }

    public Question getNext() {
	return questions.get(current++);
    }

    public boolean hasNext() {
	return questions.size() - 1 > current;
    }

    private Chapter getChapterForQuestion(Question question) {
	for (Chapter chapter : chapters) {
	    if (chapter.getQuestions().contains(question)) {
		return chapter;
	    }
	}
	throw new RuntimeException("Question doesn't have chapter");
    }

    public void answer(Answer answer, String qid) {
	int i = current - 1;
	if (questions.size() > i) {
	    Question question = questions.get(i);
	    if (qid != null && Integer.parseInt(qid) == question.getId()) {
		answerMap.put(question, isRight(answer, question));
	    } else {
		throw new RuntimeException("Do not cheat");
	    }
	}
    }

    private boolean isRight(Answer answer, Question question) {
	return question.getAnswers().get(0).getId() == answer.getId();
    }

    public Collection<Chapter> getFailedChapters() {
	for (Question q : questions) {
	    Boolean an = answerMap.get(q);
	    if (an == null) {
		answerMap.put(q, false);
	    }
	}
	Set<Chapter> res = new HashSet<Chapter>();
	for (Entry<Question, Boolean> answer : answerMap.entrySet()) {
	    if (!answer.getValue()) {
		res.add(getChapterForQuestion(answer.getKey()));
	    }
	}
	List<Chapter> lst = new ArrayList<Chapter>(res);
	Collections.sort(lst);
	return lst;
    }

    public int getTotalQuestionsCount() {
	return questions.size();
    }

    public int getRightAnswersCount() {
	int count = 0;
	for (Entry<Question, Boolean> a : answerMap.entrySet()) {
	    if (a.getValue()) {
		count++;
	    }
	}
	return count;
    }

    public BigDecimal getPercent() {
	BigDecimal right = new BigDecimal(getRightAnswersCount());
	BigDecimal total = new BigDecimal(getTotalQuestionsCount());
	BigDecimal res = right.divide(total, 2, BigDecimal.ROUND_HALF_UP)
		.multiply(new BigDecimal(100));
	return res;
    }
}
